package cn.pconline.autoclub.service;

import cn.pconline.autoclub.entity.Club;
import cn.pconline.autoclub.entity.ClubAwardRecord;
import cn.pconline.autoclub.entity.ClubLevel;
import cn.pconline.autoclub.entity.ClubMember;
import cn.pconline.autoclub.entity.ClubPetrol;
import cn.pconline.autoclub.entity.ClubUpgradePrize;
import cn.pconline.autoclub.entity.User;
import cn.pconline.autoclub.mq.SimpleMqClient;
import cn.pconline.autoclub.util.DateUtils;
import cn.pconline.autoclub.util.Pager;
import cn.pconline.autoclub.util.WebUtils;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.lang.StringUtils;
import org.gelivable.dao.GeliDao;
import org.gelivable.dao.SqlBuilder;
import org.gelivable.web.Env;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

/**
 * 车友会等级条件Service
 */
public class ClubLevelService {

    @Autowired
    private GeliDao geliDao;
    @Autowired
    private ClubAwardRecordService clubAwardRecordService;
    @Autowired
    private MemberService memberService;
    @Autowired
    private MessageService messageService;
    @Autowired
    private ClubService clubService;
    @Autowired
    private PagerService pagerService;
    @Autowired
    private SimpleMqClient simpleMqClient;
    private String cacheKey = "_cache_club_levels_key_";
    //0:未判断  
    public static final int NOT_CHECK = 0;
    //1 ： 人数不足
    public static final int VIP_NUM_LESS = 1;
    //2： 油值不足
    public static final int PETROL_LESS = 2;
    //3 ：人数油值都不满足
    public static final int VIP_NUM_PETROL_LESS = 3;
    //4 :已经升到顶级
    public static final int TOP_LEVEL = 4;
    // 5: 人数油值满足
    public static final int CAN_UP_LEVEL = 5;
    private static final Logger log = LoggerFactory.getLogger(ClubLevelService.class);

    @Transactional(propagation = Propagation.REQUIRED, readOnly = false)
    public long create(ClubLevel o) {
        geliDao.deleteCache(cacheKey);
        return geliDao.create(o);
    }

    @Transactional(propagation = Propagation.REQUIRED, readOnly = false)
    public long update(ClubLevel o) {
        geliDao.deleteCache(cacheKey);
        return geliDao.update(o);
    }

    public ClubLevel getById(long id) {
        try {
            return geliDao.find(ClubLevel.class, id);
        } catch (DataAccessException e) {
            return null;
        }
    }

    /**
     * 获取当前车友会等级的下一级所相差的油值
     *
     * @param levelId
     * @param currentPetrol
     * @return
     */
    public int getNextLevelNeedPetrol(long levelId, int currentPetrol) {
        int result = Integer.MAX_VALUE;
        List<ClubLevel> levels = getAllLevels();
        for (ClubLevel level : levels) {
            if (level.getLevelId() == levelId) {
                result = level.getLevelPetrol() - currentPetrol;
                break;
            }
        }
        return result;
    }

    /**
     * 获取当前车友会等级的下一级所相差的认证用户数
     *
     * @param levelId
     * @param currentVips
     * @return
     */
    public int getNextLevelNeedMember(long levelId, int currentVips) {
        int result = Integer.MAX_VALUE;
        List<ClubLevel> levels = getAllLevels();
        for (ClubLevel level : levels) {
            if (level.getLevelId() == levelId) {
                result = level.getLevelMember() - currentVips;
                break;
            }
        }
        return result;
    }

    /**
     * 获取车友会等级名称
     *
     * @param levelId
     * @return
     */
    public String getClubLevelNameById(long levelId) {
        ClubLevel level = null;
        try {
            level = geliDao.find(ClubLevel.class, levelId);
        } catch (EmptyResultDataAccessException e) {
        }

        return level == null ? "初建期" : level.getLevelName();
    }

    /**
     * 获取当前所有等级
     *
     * @return
     */
    public List<ClubLevel> getAllLevels() {

        List<ClubLevel> clubLevels = JSONArray.parseArray((String) geliDao.getCache(cacheKey), ClubLevel.class);
        if (clubLevels != null) {
            return clubLevels;
        }
        clubLevels = geliDao.list(
                ClubLevel.class, "select level_id, level_name, level_petrol, level_member from ac_club_level");
        geliDao.setCache(cacheKey, geliDao.object2String(clubLevels));

        return clubLevels;
    }

    public ClubLevel getByName(String name) {
        return geliDao.findFirst(ClubLevel.class,
                "select level_id, level_name, level_petrol, level_member from ac_club_level where level_name = ?",
                name);
    }

    /**
     * 积分从小到大排列
     *
     * @return
     */
    public List<ClubLevel> getSortLevels() {
        List<ClubLevel> list = getAllLevels();
        sort(list);
        return list;
    }

    /**
     * 是否最高级
     *
     * @param levelId
     * @return
     */
    public boolean isHighest(long levelId) {
        List<ClubLevel> list = getSortLevels();
        if (list != null && list.size() > 0) {
            return list.get(list.size() - 1).getLevelId() == levelId;
        }

        return false;
    }

    /**
     * 是否合法
     *
     * @param levelId
     * @return
     */
    public boolean isLeagle(long levelId) {
        List<ClubLevel> list = getSortLevels();
        if (list != null && list.size() > 0) {
            return levelId <= list.get(list.size() - 1).getLevelId()
                    && levelId >= list.get(0).getLevelId();
        }
        return false;
    }

    /**
     * 是否初建期
     *
     * @param levelId
     * @return
     */
    public boolean isLeast(long levelId) {
        List<ClubLevel> list = getSortLevels();
        if (list != null && list.size() > 0) {
            return list.get(0).getLevelId() == levelId;
        }
        return false;
    }

    /**
     * 按积分大小排列
     *
     * @param clubLevels
     */
    private void sort(List<ClubLevel> clubLevels) {
        Collections.sort(clubLevels, new Comparator<ClubLevel>() {
            @Override
            public int compare(ClubLevel c1, ClubLevel c2) {
                return c1.getLevelPetrol() > c2.getLevelPetrol()
                        ? 1 : (c1.getLevelPetrol() == c2.getLevelPetrol() ? 0 : -1);
            }
        });
    }

    /**
     * 判断车友会是否满足升级条件 0:未判断 1 ： 人数不足 2： 油值不足 3 ：人数油值都不满足 4 :已经升到顶级 5: 人数油值满足
     *
     * @param club
     * @return
     */
    public int isUpLevel(Club club) {
        int result = 0;
        ClubPetrol clubPetrol = geliDao.find(ClubPetrol.class, club.getClubId());
        int totalPetrol = (int) clubPetrol.getTotalPetrol();
        int vipNum = (int) club.getVipNum();
        ClubLevel nextLevel = getNextLevel(club.getLevelId());
        if (nextLevel == null) {
            return TOP_LEVEL;
        }
        //油值不足
        if (getNextLevelNeedPetrol(nextLevel.getLevelId(), totalPetrol) > 0) {
            result = PETROL_LESS;
        }
        //人数不足
        if (getNextLevelNeedMember(nextLevel.getLevelId(), vipNum) > 0) {
            result = VIP_NUM_LESS;
        }
        //油值和人数都不满足
        if (getNextLevelNeedPetrol(nextLevel.getLevelId(), totalPetrol) > 0
                && getNextLevelNeedMember(nextLevel.getLevelId(), vipNum) > 0) {
            result = VIP_NUM_PETROL_LESS;
        }
        //条件已满足
        if (getNextLevelNeedPetrol(nextLevel.getLevelId(), totalPetrol) <= 0
                && getNextLevelNeedMember(nextLevel.getLevelId(), vipNum) <= 0) {
            result = CAN_UP_LEVEL;
        }
        return result;

    }

    /**
     * 判断车友会是否满足降级条件 0:未判断 1 ： 人数不足要降级 2： 油值不足要降级 3 ：人数油值都不满足要降级 4：不用降级
     *
     * @param club
     * @return
     */
    public int isDownLevel(Club club) {
        int result = 0;
        ClubPetrol clubPetrol = geliDao.find(ClubPetrol.class, club.getClubId());
        int totalPetrol = (int) clubPetrol.getTotalPetrol();
        int vipNum = (int) club.getVipNum();
        long levelId = club.getLevelId();
        ClubLevel clubLevel = this.geliDao.find(ClubLevel.class, levelId);
        //当人数不足
        if (vipNum < clubLevel.getLevelMember()) {
            result = 1;
        }
        //当油值不足
        if (totalPetrol < clubLevel.getLevelPetrol()) {
            result = 2;
        }
        //当油值和人数都不满足
        if (totalPetrol < clubLevel.getLevelPetrol() && vipNum < clubLevel.getLevelMember()) {
            result = 3;
        }
        //不用降级
        if (totalPetrol >= clubLevel.getLevelPetrol() && vipNum >= clubLevel.getLevelMember()) {
            result = 4;
        }
        return result;
    }

    /**
     * 获取下一等级，当先配置表的index范围是0-5
     *
     * @param levelId
     * @return
     */
    public ClubLevel getNextLevel(long levelId) {
        List<ClubLevel> levels = getSortLevels();
        if (levels == null) {
            return null;
        }
        int currentIndex = getIndex(levels, levelId);
        if ((currentIndex + 1) <= 0) {
            return null;
        }
        if ((currentIndex + 1) > levels.size() - 1) {
            return null;
        }
        return levels.get(currentIndex + 1);
    }

    public ClubLevel getPreLevel(long levelId) {
        List<ClubLevel> levels = getSortLevels();
        if (isLeast(levelId)) {
            return null;
        }
        if (levels == null) {
            return null;
        }
        int currentIndex = getIndex(levels, levelId);
        if (currentIndex == -1 || currentIndex == 0) {
            return null;
        }
        return levels.get(currentIndex - 1);
    }

    private int getIndex(List<ClubLevel> list, long levelId) {
        for (int i = 0; i < list.size(); i++) {
            ClubLevel c = list.get(i);
            if (c.getLevelId() == levelId) {
                return i;
            }
        }
        return -1;
    }
    /*
     * 发送车友会升级系统消息
     * 给管理员发
     */

    public void sendClubUpLevel(Club club, long curLevelId) {
        if (club == null || curLevelId < 0) {
            return;
        }
        ClubLevel nextLevel = getNextLevel(curLevelId);
        ClubAwardRecord car = clubAwardRecordService.findByClubId(club.getClubId(), nextLevel.getLevelId());
        if (car == null) {
            car = clubAwardRecordService.autoInsert(club.getClubId(), nextLevel.getLevelId());
        }
        if (car.getIsSend() == ClubAwardRecord.IS_UPSEND_YES) {
            return;
        }
//        StringBuilder str = new StringBuilder();
//        str.append("恭喜您！您所管理的车友会<a href='").append(messageService.getRoot()).append("/").append(club.getClubId()).append("/'>").append(club.getName()).append("</a>符合");
//        str.append(nextLevel.getLevelName()).append("要求，您现在可以");
//        str.append("<a href='").append(messageService.getRoot()).append("/club/levelPrizes.do?clubId=").append(club.getClubId()).append("'>立即升级</a>车友会!");
//        List<ClubMember> admins = memberService.listAdmins(club.getClubId());
//        for (ClubMember c : admins) {
//            User user = new User();
//            user.setUid(c.getUid());
//            messageService.send(user, str.toString());
//        }
        ClubMember a = memberService.findAdminByClubId(club.getClubId());
        User user = new User();
        user.setUid(a.getUid());
        messageService.send(user, messageService.getAdminUpLevelMsg(club.getClubUrl(), club.getName(), nextLevel.getLevelName()));
        car.setIsSend(ClubAwardRecord.IS_UPSEND_YES);
        clubAwardRecordService.update(car);
    }

    /**升级后给车友会所有成员发送升级消息
     * @param clubId
     * @param giftInfo   发送给会长的礼物清单信息
     */
    public void setMsgToMember(long clubId, String giftInfo) {
        if (clubId < 1) {
            return;
        }
        Club club = clubService.getClub(clubId);
        ClubLevel level = this.getById(club.getLevelId());

//    	String clubUrl = clubService.getClubIndexUrl(club.getClubId(),club.getClubUrl());
        String msg1 = messageService.assembleClubUrl(club.getClubUrl(), club.getName());

        List<ClubMember> listMember = memberService.listMemberByClubId(clubId);
        if (listMember != null && !listMember.isEmpty()) {
            for (ClubMember member : listMember) {
                User user = new User();
                user.setUid(member.getUid());
                	messageService.send(user, MessageService.UP_LEVEL + MessageService.GIFT_INFO, 
                			msg1, level.getLevelName(), giftInfo);
            }
        }
    }

    /**
     * 发送车友会降级系统消息 给管理员发
     *
     * @param club
     * @param curLevel
     * @param isDown 降级原因
     */
    public void sendClubDownLevel(Club club, ClubLevel curLevel, int isDown) {
        if (club == null || curLevel == null) {
            return;
        }

        ClubAwardRecord car = clubAwardRecordService.findByClubId(club.getClubId(), curLevel.getLevelId());
        if (car == null) {
            return;
        }
        if (car.getIsSend() == ClubAwardRecord.IS_DOWNSEND_YES) {
            return;
        }

        String msg1 = messageService.assembleClubUrl(club.getClubUrl(), club.getName());
        String msg2 = "不满足该等级要求";
        if (isDown == 1) {
            msg2 = ("认证人数");
        } else if (isDown == 2) {
            msg2 = ("油值");
        } else if (isDown == 3) {
            msg2 = ("认证人数和油值");
        }

        List<ClubMember> admins = memberService.listAdmins(club.getClubId());
        car.setIsSend(ClubAwardRecord.IS_DOWNSEND_YES);
        clubAwardRecordService.update(car);
        for (ClubMember c : admins) {
            User user = new User();
            user.setUid(c.getUid());
            messageService.send(user, MessageService.DOWN_LEVEL, msg1, msg2);
        }

    }

    //-----------------后台管理start
    /**
     * 等级列表
     *
     * @param name
     * @param pageNo
     * @param pageSize
     * @return
     */
    public Pager<ClubLevel> pagerBy(String name, int pageNo, int pageSize) {

        SqlBuilder sql = new SqlBuilder();
        sql.appendSql(" select level_id from ac_club_level").appendSql(" where 1=1 ");
        if (StringUtils.isNotBlank(name)) {
            sql.appendSql(" and level_name = ").appendValue(name);
        }
        return pagerService.pager(ClubLevel.class, sql, pageNo, pageSize);
    }

    /**
     * 根据等级ID获取奖品列表
     *
     * @param levelId
     * @return
     */
    public List<ClubUpgradePrize> listPrizeByLevelId(long levelId) {
        if (levelId < 1) {
            return null;
        }
        SqlBuilder sql = new SqlBuilder();
        sql.appendSql("select club_upgrade_prize_id from ac_club_upgrade_prize");
        sql.appendSql(" where level_id = ").appendValue(levelId);
        return geliDao.list(ClubUpgradePrize.class, sql.getSql(), sql.getValues());
    }

    /**
     * 保存等级信息
     *
     * @param req
     * @return
     */
    public long updateSaveLevel(HttpServletRequest req, Env env) {

        ClubLevel level = env.bind(ClubLevel.class);
        long i = geliDao.update(level);
        this.updateSavePrize(req, level.getLevelId());
        return i;
    }

    /**
     * 保存奖品
     *
     * @param req
     * @return
     */
    public void updateSavePrize(HttpServletRequest req, long levelId) {
        try {
            int step = 0;
            boolean isSetTextLink = true;
            while (isSetTextLink) {
                String prize = WebUtils.param(req, "items[" + step + "].prize", "");
                if (StringUtils.isNotBlank(prize)) {
                    long prizeId = WebUtils.paramLong(req, "items[" + step + "].prizeId", 0);
                    ClubUpgradePrize clubUpgradePrize = new ClubUpgradePrize();
                    clubUpgradePrize.setPrize(prize);
                    clubUpgradePrize.setClubUpgradePrizeId(prizeId);
                    clubUpgradePrize.setLevelId(levelId);
                    if (prizeId > 0) {
                        geliDao.update(clubUpgradePrize);
                    } else {
                        geliDao.create(clubUpgradePrize);
                    }
                    step++;
                } else {
                    isSetTextLink = false;
                }
            }
        } catch (DuplicateKeyException e) {
            log.error("保存奖品出错,id:" + levelId, e);
        }
    }

    /**
     * 根据礼品ID删除数据
     *
     * @param id
     */
    public void removePrizeById(long id) {
        if (id < 1) {
            return;
        }
        ClubUpgradePrize price = geliDao.find(ClubUpgradePrize.class, id);
        geliDao.delete(price, id);
    }
    //-----------------后台管理end
    
    /**
     * 车友会升级发送MQ同步任务状态
     * @param club 
     */
    public void sendUpgrade(Club club){
        if(club == null) return;
        List<ClubMember> clubMembers = memberService.listVipMember(club.getClubId());
        if(clubMembers!=null && !clubMembers.isEmpty()){
            Date now = DateUtils.getNow();
            for(ClubMember clubMember : clubMembers){
                JSONObject obj = new JSONObject();
                obj.put("userId", clubMember.getUid());
                obj.put("clubId", club.getClubId());
                obj.put("levelId", club.getLevelId());
                obj.put("createAt",now);
                simpleMqClient.sendUpgradeMessage(obj);
            }
        }
    }
}
